package MTClient;

import java.util.ArrayList;

import MTRequest.MTRequestDataSource;
import SQLManager.SQLManager;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.ConnectivityManager;
import android.telephony.TelephonyManager;
import event.money.tracker.EditEvent;
import event.money.tracker.EventDetails;
import event.money.tracker.MainContacts;
import event.money.tracker.MainEvents;
import event.money.tracker.MoneyTrackerActivity;


public class ClientLogic implements MTRequestDataSource{
	
	/////////////////////////////////////////////////////////////
	// vars
	/////////////////////////////////////////////////////////////
	
	
	private static Context mGlobalContext = null;
	private static Activity mCurrentActivity = null;
	private static ClientLogic mLogic = new ClientLogic();
	int mRequestID;
	
	ArrayList< String > mRawString = new ArrayList();
	private Context mRequestActivity = null;
	
	/////////////////////////////////////////////////////////////
	// static public interface
	/////////////////////////////////////////////////////////////
	
	public static void SetCurrentActivity(Activity view) {
		mCurrentActivity = view;
	}
	
	public static ClientLogic GetInstance()
	{
		if( null == mLogic ){
			mLogic = new ClientLogic();
		}
		return mLogic;
	}
	
	/////////////////////////////////////////////////////////////
	// public interface
	/////////////////////////////////////////////////////////////
	
	public void init(Context aContext) {
		
		SQLManager.CreateIntance( aContext );
        SQLManager.GetInstance().open();
        
        mGlobalContext = aContext;
	}
	
	public void destroy(Context aContext) {
		
		
	}
	
	public String get_phone_number(){
		
		TelephonyManager mTelephonyMgr;
        mTelephonyMgr = (TelephonyManager)mGlobalContext.getSystemService(Context.TELEPHONY_SERVICE); 
        return mTelephonyMgr.getLine1Number();
	}
	
	public boolean pref_check_user_known(){
		
		SharedPreferences pref = mGlobalContext.getSharedPreferences( "event.money.tracker", Context.MODE_PRIVATE );
		return pref.getBoolean("user_known", false);		
	}
	
	/////////////////////////////////////////////////////////////
	// request methods
	/////////////////////////////////////////////////////////////

	public boolean SendRegisterRequest( String phone, String name, Context aContext )
	{
		mRequestID = MTConstant.MT_REQID_REGISTER;
		if( CheckInternetConnected() ){
			this.mRawString.clear();
			//Add Raw Data
			this.mRawString.add( phone );
			this.mRawString.add( name );
			
			mRequestActivity = aContext;
			
			ClientTCPConnection.GetInstance().SendRequest( MTConstant.MT_REQID_REGISTER , mLogic );
			return true;
		}
		return false;
	}
	
	public boolean SendCreateEventRequest( String aTitle, String aContactMemebr, String aLocation )
	{
		mRequestID = MTConstant.MT_REQID_CREATE_EVENT;
		this.mRawString.clear();
		//Add Raw Data
		this.mRawString.add( aTitle );
		this.mRawString.add( aContactMemebr );
		this.mRawString.add( aLocation );
		
		if( CheckInternetConnected() ){
			// Send Data to Server
			ClientTCPConnection.GetInstance().SendRequest( MTConstant.MT_REQID_CREATE_EVENT , mLogic );
			return true;
		}
		else{
			String lastTempID = CreateEvent( null, null );
			
			// Put into Update Table
			SQLManager.GetInstance().open();
			SQLManager.GetInstance().InsertUpdateTable( lastTempID, GetUserID(), "", MTConstant.MT_ID_UPT_CREATE_TABLE );
			SQLManager.GetInstance().close();
			return false;
		}
	}
	
	public boolean SendSynLocalDBRequest()
	{
		this.mRawString.clear();
		if( CheckInternetConnected() ){
			mRequestID = MTConstant.MT_REQID_SYNCHRONIZE_DATA_FROM_LOCAL_DB;
			ClientTCPConnection.GetInstance().SendRequest( MTConstant.MT_REQID_SYNCHRONIZE_DATA_FROM_LOCAL_DB , mLogic );
			return true;
		}
		return false;
	}
	
	public boolean SendStackTakeEventRequest(String event_id)
	{
		this.mRawString.clear();
		
		this.mRawString.add(event_id);
		
		// Check whether Master request
		
		if( CheckInternetConnected() ){
			mRequestID = MTConstant.MT_REQID_STOCK_TAKE_EVENT;
			ClientTCPConnection.GetInstance().SendRequest( MTConstant.MT_REQID_STOCK_TAKE_EVENT , mLogic );
			return true;
		}
		return false;
	}
	
	public boolean SendSynContactListRequest()
	{
		this.mRawString.clear();
		
		if( CheckInternetConnected() ){
			mRequestID = MTConstant.MT_REQID_SYNCHRONIZE_CONTACT_LIST;
			ClientTCPConnection.GetInstance().SendRequest( MTConstant.MT_REQID_SYNCHRONIZE_CONTACT_LIST , mLogic );
			return true;
		} else {
			return false;
		}
	}
	
	public boolean SendSynServerDBRequest()
	{
		mRequestID = MTConstant.MT_REQID_SYNCHRONIZE_DATA_FROM_SERVER;
		this.mRawString.clear();
		if( CheckInternetConnected() ){
			ClientTCPConnection.GetInstance().SendRequest( MTConstant.MT_REQID_SYNCHRONIZE_DATA_FROM_SERVER , mLogic );
			return true;
		}
		return false;
	}
	
	/////////////////////////////////////////////////////////////
	// logic
	/////////////////////////////////////////////////////////////
	
	public void AddProduct( String aTempEventID, String aProductName, String aDescription, String aPrice, String aQuality, String aImage  )
	{
		SQLManager sqlManager = SQLManager.GetInstance();
		sqlManager.open();
		// Insert New Product
		sqlManager.InsertProduct( 
				aTempEventID,
				GetUserID(),
				aProductName,
				aDescription,
				aPrice,
				aQuality,
				aImage );
		
		// Insert a new item in update table
		
		String tableName = String.format( SQLManager.TB_PRODUCT_TABLE, aTempEventID );
    	String lastIndex = sqlManager.GetLastIndex( tableName );
    	System.out.println("Last Index:" + lastIndex );
    	String eventId = sqlManager.GetExistEventID( aTempEventID );
    	if( null != eventId ){
    		System.out.println( "EventID Exist!");
    		sqlManager.InsertUpdateTable( aTempEventID, GetUserID(), lastIndex, MTConstant.MT_ID_UPT_CREATE_PRODUCT );
    	}
		sqlManager.close();
	}
	
	public void UpdateProductID( String aTempEventID, String aID, String aProductID )
	{
		
	}
	
	// When get a EventID, do it to add product to UpdateTable
	public void SynProductListAddedBefore()
	{
		
	}
	
	public void del_shared_prefs( ) {
		
		SharedPreferences pref = mGlobalContext.getSharedPreferences( "event.money.tracker", Context.MODE_PRIVATE );
		SharedPreferences.Editor pref_edit = pref.edit();
		pref_edit.remove("user_known");
		pref_edit.commit();
		
		return;
	}
	
	public void del_sqldb() {
		SQLManager sqlManager = SQLManager.GetInstance();
		
		sqlManager.DeleteDB();
	}
	
	public static String GetUserID()
	{
		SharedPreferences pref = mGlobalContext.getSharedPreferences( "event.money.tracker", Context.MODE_PRIVATE );
		return pref.getString("UserID", null );
	}
	
	public String GetUserName()
	{
		SharedPreferences pref = mGlobalContext.getSharedPreferences( "event.money.tracker", Context.MODE_PRIVATE );
		return pref.getString("user_name", null );
	}
	
	public String GetUserNameFromID(String aUserID)
	{
	
		// get user name
		String MasterUsername = null;
		if( ClientLogic.GetInstance().GetUserID().matches( aUserID ) ){
			MasterUsername = ClientLogic.GetInstance().GetUserName();
		}else{
			Cursor MasterCur = SQLManager.GetInstance().FetchUser(aUserID);
			MasterCur.moveToFirst();
			MasterUsername = MasterCur.getString(MasterCur.getColumnIndex("UserName"));
		}
		
		return MasterUsername;
	}

	public String CreateEvent(
			String aEventID, String error) {
		//
		//Update SQL database
		//
		
		SQLManager sqlManager = SQLManager.GetInstance();
		sqlManager.open();
		
		// Create Product List
		
		sqlManager.InsertEvent( 
				aEventID, 
				GetUserID(),
				this.mRawString.get( 0 ), 
				this.mRawString.get( 1 ), 
				this.mRawString.get( 2 ) );
		
		String lastIndex = sqlManager.GetLastIndex( SQLManager.TB_EVENTTABLE );
		System.out.println( "Last Index: " + lastIndex );
		sqlManager.CreateProductList( lastIndex );
		
		sqlManager.close();
		return lastIndex;
	}
	
	
	/////////////////////////////////////////////////////////////
	// callbacks
	/////////////////////////////////////////////////////////////
	
	@Override
	public String GetRawData() {
		
		switch( mRequestID ){
			case MTConstant.MT_REQID_STOCK_TAKE_EVENT:{
				return this.mRawString.get( 0 );				
			}
			case MTConstant.MT_REQID_REGISTER:{
				switch( ClientTCPConnection.GetInstance().GetMSGCenter().GetRequest().GetRequestState() ){
					case MTConstant.MT_REQ_CREG_SEND_PHONENUM:{			
						return this.mRawString.get( 0 );
					}
					case MTConstant.MT_REQ_CREG_SEND_USER_INFO:{
						return this.mRawString.get( 1 );
					}
				}
			}
			case MTConstant.MT_REQID_CREATE_EVENT:{
				
				String rawData = String.format( 
						GetUserID() + MTConstant.MT_REQ_RAW_DATA_SEPARATER +
						"'%s'" + MTConstant.MT_REQ_RAW_DATA_SEPARATER +
						"'%s'" + MTConstant.MT_REQ_RAW_DATA_SEPARATER +
						"'%s'", 
						this.mRawString.get( 0 ),
						this.mRawString.get( 1 ),
						this.mRawString.get( 2 ) );
				return rawData;
			}
			case MTConstant.MT_REQID_SYNCHRONIZE_CONTACT_LIST:
			case MTConstant.MT_REQID_SYNCHRONIZE_DATA_FROM_SERVER:{
				return GetUserID();
			}
			case MTConstant.MT_REQID_SYNCHRONIZE_DATA_FROM_LOCAL_DB:{
				switch( ClientTCPConnection.GetInstance().GetMSGCenter().GetRequest().GetRequestState() ){
					case MTConstant.MT_REQ_CSYN_DFLDB_SYNCHRONIZE_REQUEST:{			
						return GetUserID();
					}
					case MTConstant.MT_REQ_CSYN_DFLDB_PREPARE_PRODUCT:{
						return this.mRawString.get( 0 );
					}
				}
			}
			
		}
		
		return null;
	}

	@Override
	public void Notify(int RequestID, int RequestState, String aRawData ) {
		
		switch( RequestID ){
			case MTConstant.MT_REQID_REGISTER:{
				if( null != aRawData ){
					
			    	if(ClientLogic.GetInstance().register_user( this.mRawString.get(0),this.mRawString.get(1), aRawData))
			    	{
			    		if(mCurrentActivity instanceof MoneyTrackerActivity)
			    			((MoneyTrackerActivity)mCurrentActivity).handle_register_result(true);
			    		
			    		System.out.println( "Register Success!" );
			    		System.out.println( "User ID :" + GetUserID() );
			    	} 
				}
				else{
					((MoneyTrackerActivity)mCurrentActivity).handle_register_result(false);
					System.out.println( "Cannot't register!" );
				}
				break;
			}
			case MTConstant.MT_REQID_CREATE_EVENT:{
				CreateEvent( aRawData, null );
				if(mCurrentActivity instanceof EditEvent)
					((EditEvent)mCurrentActivity).handle_eventCreation(true);
					
				break;
			}
			case MTConstant.MT_REQID_SYNCHRONIZE_DATA_FROM_LOCAL_DB:{

				this.SendSynServerDBRequest();
				
				break;
			}
			case MTConstant.MT_REQID_SYNCHRONIZE_DATA_FROM_SERVER:{
				
				if(RequestState == MTConstant.MT_REQ_SSYN_DFSDB_UPDATED_PRODUCT_LAST || 
						RequestState == MTConstant.MT_REQ_SSYN_DFSDB_NO_UPDATED) {
					if(mCurrentActivity instanceof MainEvents)
						((MainEvents)mCurrentActivity).handle_sync_result();
				}
					
					
				break;
			}
			case MTConstant.MT_REQ_SSYN_CTL_REPLY_PHONENUM_LAST:{
				
				if(mCurrentActivity instanceof MainContacts){
					System.out.println("((MainContacts)mCurrentActivity).handle_update_result(true)");
	    			((MainContacts)mCurrentActivity).handle_update_result(true);
				}
				
				break;
			}
			case MTConstant.MT_REQID_STOCK_TAKE_EVENT:{
				
				if(RequestState == MTConstant.MT_REQ_SSTE_STOCK_TAKE_FINISH) {
					if(mCurrentActivity instanceof EventDetails)
						((EventDetails)mCurrentActivity).handle_terminate_result(true);
				} else
					if(mCurrentActivity instanceof EventDetails)
			    		((EventDetails)mCurrentActivity).handle_terminate_result(false);
				
				break;
			}
		}
	}
	
	/////////////////////////////////////////////////////////////
	// private methods
	/////////////////////////////////////////////////////////////
	
	private boolean CheckInternetConnected()
	{
		 final ConnectivityManager connMgr = (ConnectivityManager)
		 mGlobalContext.getSystemService(Context.CONNECTIVITY_SERVICE);

		 final android.net.NetworkInfo wifi =
		 connMgr.getNetworkInfo( ConnectivityManager.TYPE_WIFI );

		 final android.net.NetworkInfo mobile =
		 connMgr.getNetworkInfo( ConnectivityManager.TYPE_MOBILE );

		 if( wifi.isConnected() ){
			 System.out.println( "Wifi Connected." );
			 return true;
		 }
		 
		 if( mobile.isConnected() ){
			 System.out.println( "3G Connected." );
			 return true;
		 }
		 
		 System.out.println( "No Network Connected." );
		 
		 return false;
	}
		
	
	private boolean register_user( String phone, String name, String aUserID) {
		// only saves in shared prefs!
		
		SharedPreferences pref = mGlobalContext.getSharedPreferences( "event.money.tracker", Context.MODE_PRIVATE );
		SharedPreferences.Editor pref_edit = pref.edit();
		pref_edit.putString("phone_nr", phone);
		pref_edit.putString("user_name", name);
		pref_edit.putBoolean("user_known", true);
		pref_edit.putString("UserID", aUserID );
		pref_edit.commit();
		
		return true;
	}
	
}
